#pragma once

#include "DLL.h"
#include <MyFC/Event.h>

namespace My {

class Sequence;

enum PlayMode {
	PlayStop,
	PlayForward,
	PlayBackward,
	PlayFollow
};

class DLL_API Player : public EventDispatcher
{
public:
	class PlaymodeChange;
public:
	Player();
	~Player();
	void SetLoop(bool Loop) { m_Loop = Loop; }
	bool GetLoop() const { return m_Loop; }
	bool ToggleLoop() { return m_Loop = !m_Loop; }
	void SetAutoFollow(bool AutoFollow) { m_AutoFollow = AutoFollow; }
	bool GetAutoFollow() const { return m_AutoFollow; }
	bool ToggleAutoFollow() { return m_AutoFollow = !m_AutoFollow; }
public:
	/// If PlayMode is PlayStop or PlayFollow do nothing, otherwise changes position of Sequence's preview time
	void TimeStep();
	/// Return frame number of the following frame, or current preview time if PlayMode is PlayStop;
	/// ChangeDirection receives true if play direction is changingdue to bound bouncing
	int NextFrame(bool * ChangeDirection = 0) const;
	/// Activates or disactivates playback
	void SetPlayMode(PlayMode m);
	PlayMode GetPlayMode() const { return m_PlayMode; }
	void StartFollow() { if (m_AutoFollow) SetPlayMode(PlayFollow); }
	bool IsPlaying() const { return m_PlayMode != PlayStop && m_PlayMode != PlayFollow; }
protected: //subclasses should provide means to initiate timing and call TimeStep() on each timer event
	virtual void StartTimer() = 0;
	virtual void StopTimer() = 0;
	virtual Sequence * GetSequence() const = 0;
	virtual void OnActivateFollow() { }
	virtual void OnDeactivateFollow() { }
private:
	void WriteSettings();
	void ReadSettings();
private:
	PlayMode m_PlayMode;
	bool m_Loop;
	bool m_AutoFollow;
};

class Player::PlaymodeChange : public Event {
public:
	Player &	m_Player;
	PlaymodeChange(Player & p) : m_Player(p) { }
};

} //namespace My
